(function(win) {
    var tool = {

        /**
         * json 转化为url
         * @param {any} json
         * @returns
         */
        json2url: function(json) {
            var arr = [];
            for (var name in json) {
                if (json.hasOwnProperty(name)) {
                    arr.push(name + '=' + json[name]);
                }
            }
            return arr.join('&');
        },

        /**
         * ajax
         * @param {any} json
         * @returns
         */
        ajax: function(json) {
            // 给json的参数赋初始值
            if (!json.url) {
                alert('请填写url');
                return;
            }
            json.data = json.data || {};
            json.type = json.type || 'get';
            json.timeout = json.timeout || 3000;
            var timer = null;
            // 准备ajax对象
            // 利用if函数判断准备ajax对象的方法(非IE6与其他浏览器不同，利用定义属性的方法)
            var oAjax;
            if (window.XMLHttpRequest) {
                // 支持非IE6的浏览器
                oAjax = new XMLHttpRequest();
            } else {
                // 支持IE6浏览器
                oAjax = new ActiveXObject('Microsoft.XMLHTTP');
            }
            // 利用switch方法判断传输方式
            switch (json.type.toLowerCase()) {
                // 利用get方式传输
                case 'get':
                    // 建立连接
                    oAjax.open('GET', json.url + '?' + tool.json2url(json.data), true);
                    // 发送数据(发送载体是url，不需要填写值)
                    oAjax.send();
                    break;
                    // 利用post方式传输
                case 'post':
                    // 建立连接
                    oAjax.open('POST', json.url, true);
                    // post没有发送载体，必须先设置头
                    oAjax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                    // 发送数据，需要转字符串
                    oAjax.send(tool.json2url(json.data));
                    break;
            }
            // 接收数据
            // 监控数据加载状况
            oAjax.onreadystatechange = function() {
                // 利用if函数判断通信状况
                if (oAjax.readyState == 4) {
                    clearTimeout(timer);
                    // 利用if函数判断HTTP状态码情况
                    if (oAjax.status >= 200 && oAjax.status < 300 || oAjax.status == 304) {
                        // 返回接收成功的函数
                        json.success && json.success(oAjax.responseText);
                    } else {
                        // 返回接收失败的函数
                        json.error && json.error(oAjax.status);
                    }
                }
            };
            // 设置超时的执行函数
            timer = setTimeout(function() {
                alert('您的网络不给力');
                // 清除onreadystatechange事件
                oAjax.onreadystatechange = null;
            }, json.timeout);
        },

        /**
         * 判断是否为json
         * @param {any} json
         * @returns
         */
        isJson: function(json) {
            return Object.prototype.toString.call(json) === '[object Object]';
        },

        /**
         *  对象合并
         * @param {any} baseJson
         * @param {any} sourceJson
         * @returns
         */
        assgin: function(baseJson, sourceJson) {
            if (!tool.isJson(baseJson) || !tool.isJson(sourceJson)) return baseJson;
            for (var name in sourceJson) {
                if (sourceJson.hasOwnProperty(name)) {
                    baseJson[name] = sourceJson[name];
                }
            }
            return baseJson;
        },

        /**
         * 获取class
         * @param {any} oEle
         * @param {any} className
         * @returns
         */
        getByClass: function(oEle, className) {
            var arr;
            if (oEle.getElementsByClassName) {
                arr = oEle.getElementsByClassName(className);
            } else {
                arr = [];
                var aEle = oEle.getElementsByTagName('*');
                var reg = new RegExp('\\b' + className + '\\b');
                for (var i = 0; i < aEle.length; i++) {
                    if (reg.test(aEle[i].className)) {
                        arr.push(aEle[i]);
                    }
                }
            }
            return arr;
        },

        /**
         * 添加class
         * @param {any} obj
         * @param {any} sClass
         */
        addClass: function(obj, sClass) {
            if (obj.className) {
                if (!tool.hasClass(obj, sClass)) {
                    obj.className += ' ' + sClass;
                }
            } else {
                obj.className = sClass;
            }
        },

        /**
         * 检查class
         * @param {any} obj
         * @param {any} sClass
         * @returns
         */
        hasClass: function(obj, sClass) {
            var reg = new RegExp('\\b' + sClass + '\\b');
            return reg.test(obj.className);
        },

        /**
         * 删除class
         * @param {any} obj
         * @param {any} sClass
         */
        removeClass: function(obj, sClass) {
            var reg = new RegExp('\\b' + sClass + '\\b', 'g');
            if (tool.hasClass(obj, sClass)) {
                obj.className = obj.className.replace(reg, '').replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ');
            }
        },

        /**
         * 获取样式
         * @param {any} obj
         * @param {any} name
         * @returns
         */
        getStyle: function(obj, name) {
            return (obj.currentStyle || win.getComputedStyle(obj, false))[name];
        },

        /**
         * 设置样式
         */
        setStyle: function() {
            if (arguments.length === 2) {
                for (var name in arguments[1]) {
                    if (arguments[1].hasOwnProperty(name)) {
                        arguments[0].style[name] = arguments[1][name];
                    }
                }
            } else {
                arguments[0].style[arguments[1]] = arguments[2];
            }
        }
    };

    /**
     * markdown 读取渲染
     *
     * @param {any} opts
     */
    function FangMarkdown(opts) {
        var that = this;
        that.ops = {
            filePath: './readme.md',
            boxId: '#content'
        };
        tool.assgin(that.ops, opts);

        if (that.ops.boxId instanceof HTMLElement) {
            that.box = that.ops.boxId;
        } else if (win.jQuery && that.ops.boxId instanceof jQuery) {
            that.box = that.ops.boxId[0];
        } else {
            that.box = document.querySelector(that.ops.boxId);
        }
        that.init();
    }
    FangMarkdown.prototype = {
        init: function() {
            var that = this;
            var marked = win.marked;
            var hljs = win.hljs;
            tool.addClass(that.box, 'markdown-body');
            if (tool.getStyle(that.box,'max-width')) {
                tool.setStyle(that.box, {
                    'max-width': '1000px',
                    margin: '0 auto'
                });
            }
            marked.setOptions({
                renderer: new marked.Renderer(),
                gfm: true,
                tables: true,
                breaks: false,
                pedantic: false,
                sanitize: false,
                smartLists: true,
                smartypants: false,
                highlight: function(code) {
                    return hljs.highlightAuto(code).value;
                }
            });
            tool.ajax({
                url: that.ops.filePath,
                success: function(data) {
                    that.box.innerHTML = marked(data);
                    var title = document.getElementById('-');
                    if (title) {
                        document.title = title.innerHTML;
                    }
                },
                error: function(err) {
                    console.log(err);
                }
            });
        }
    };
    win.FangMarkdown = FangMarkdown;
    return FangMarkdown;
})(window);